#include "shell.h"
#include "shell_inner.h"
#include <stdarg.h>
#include "bsp_usart1.h"
#include "ringbuffer.h"


/* shell hardware port */


/* static var */

static char shell_cs_buff[CONFIG_SHELL_CONSOLE_SIZE * 2];
static uint8_t shell_rbuffer[CONFIG_SHELL_CMD_SIZE];
static _ringbuff_dev shell_rb_dev;
static os_sem_handle_t shell_sem = NULL;


/* static func */

static void shell_irq_rx_handler_def(int ch)
{
	if (shell_sem == NULL) return ;

	if (ch == -1)
	{
		os_sem_release(shell_sem);	//释放二值信号量
	}
	else
	{
		ch &= 0xFF;
		ringbuffer_putchar(&shell_rb_dev, ch);
	}
}


/* export func */


void shell_port_init(void)
{
    ringbuffer_init(&shell_rb_dev, shell_rbuffer, sizeof(shell_rbuffer));

    shell_sem = os_sem_binary_create();
    if (shell_sem == NULL)
    {
        printf("shell_sem create fail!\r\n");
    }

    bsp_usart1_set_irq_rx_handler(shell_irq_rx_handler_def);

}

int shell_port_set_char(char ch)
{
    return bsp_usart1_put_char(ch);
}

int shell_port_get_char(void)
{
    unsigned char ch = 0;
	
	while (ringbuffer_getchar(&shell_rb_dev, &ch) != 1)
	{
		os_sem_take(shell_sem, OS_WAIT_MAX);	//获取信号量
	}
    
	
	return (int)ch;
}

int shell_port_printf(const char *fmt, ...)
{
	va_list args;
    int length, cnt;;
    uint32_t size;
    char *ps, *pe;
	
    size = CONFIG_SHELL_CONSOLE_SIZE;

    ps = shell_cs_buff;
    pe = &shell_cs_buff[size];

	va_start(args, fmt);
	
	cnt = vsnprintf(pe, size - 1, fmt, args);
    if (cnt <= 0) return cnt;

	if (cnt > (size - 1))
	{
		cnt = size - 1;
	}

    /* auto crlf */
    length = 0;
    while (cnt--)
    {
        if (*pe == '\n')
        {
            *ps = '\r';
            ps++;
            length++;
        }
        *ps = *pe;
        ps++;
        pe++;
        length++;
    }
    ps++;
    *ps = '\0';
	
	/* device output */
    bsp_usart1_send_buff((uint8_t*)shell_cs_buff, length);
    
    // printf("%s", cs_buff);
	
	va_end(args);

    return length;
}

void shell_port_reboot(void)
{
    system_soft_reset();
}

void shell_port_chip_info(void)
{
    shell_printf("MCU: STM32H750VBT6 @%dMHz\n", SystemCoreClock/1000000);
}

uint32_t shell_port_get_freeheap(void)
{
    return 0;
}


